package com.hospital.hospitalserver.service;

import com.hospital.hospitalserver.entity.DiagnosisRecordDTO;
import com.hospital.hospitalserver.entity.PatientVisitDTO;
import com.hospital.hospitalserver.entity.Vo.DiagnosisRecord;
import com.hospital.hospitalserver.entity.Vo.PatientMaster;
import com.hospital.hospitalserver.entity.Vo.PatientVisit;
import com.hospital.hospitalserver.entity.query.DoctorDiagnosisRecordQuery;
import com.hospital.hospitalserver.enums.ResultCodeEnum;
import com.hospital.hospitalserver.exception.CustomException;
import com.hospital.hospitalserver.mapper.DiagnosisRecordMapper;
import com.hospital.hospitalserver.mapper.PatientMasterMapper;
import com.hospital.hospitalserver.mapper.PatientVisitMapper;
import com.hospital.hospitalserver.util.DiagnosisRecordNoGenerator;
import com.hospital.hospitalserver.util.PagerData;
import com.hospital.hospitalserver.util.Response;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.time.LocalDateTime;
import java.util.List;

/**
 * 诊断记录相关操作
 * */
@Service
@RequiredArgsConstructor
public class DiagnosisRecordService {
    private final PatientVisitMapper patientVisitMapper;
    private final DiagnosisRecordMapper diagnosisRecordMapper;
    private final PatientMasterMapper patientMasterMapper;

    /**
     * 查找就诊记录
     * */
    public Response selectByVisitId(DiagnosisRecordDTO request){
        DiagnosisRecord record = diagnosisRecordMapper.selectByVisitId(request.getVisit_id());
        if(record!=null){
            return Response.success(record);
        }else{
            return Response.error("未加载到记录");
        }
    }

    /**
     * 保存诊断记录
     */
    @Transactional
    public Response saveDiagnosisRecord(DiagnosisRecordDTO request) {
        // 1. 根据visit_id获取就诊信息（包含appointment_id）
        PatientVisit visit = patientVisitMapper.getPatientVisitDataByVisitID(request.getVisit_id());

        if (visit == null) {
            throw new CustomException(ResultCodeEnum.ERROR, "挂号记录不存在");
        }


        // 2. 检查患者档案是否存在，根据用户身份证唯一编号查询，如果没有则新建
        String patientIdNumber = request.getId_number();
        PatientMaster existingPatientMaster = patientMasterMapper.getPatientMasterDataByIdNumber(patientIdNumber);

        Integer patientId;
        if (existingPatientMaster != null) {
            // 存在，则取出当前用户档案的patient_id
            patientId = existingPatientMaster.getPatient_id();
            request.setPatient_id(patientId);
        } else {
            // 不存在，则新建患者档案
            throw new CustomException(ResultCodeEnum.ERROR, "没有患者档案记录，无法添加诊断信息");
        }

        // 3. 检查是否已存在诊断记录
        DiagnosisRecord existingRecord = diagnosisRecordMapper.selectByVisitId(request.getVisit_id());

        DiagnosisRecord record;
        if (existingRecord != null) {
            // 更新现有记录
            record = updateExistingRecord(existingRecord, request);
        } else {
            // 创建新记录
            record = createNewRecord(request, visit);
        }

        if (record != null) {
            return Response.success(record); // 返回记录对象而不是字符串
        } else {
            throw new CustomException(ResultCodeEnum.ERROR, "保存诊断记录失败");
        }
    }

    /**
     * 创建新诊断记录
     */
    private DiagnosisRecord createNewRecord(DiagnosisRecordDTO dto, PatientVisit visit) {
        DiagnosisRecord record = new DiagnosisRecord();

        // 设置基本信息
        record.setVisit_id(dto.getVisit_id());
        record.setRecord_no(generateRecordNo(visit.getAppointment_id()));
        record.setPatient_id(dto.getPatient_id());

        // 设置诊断内容（使用统一的方法）
        setDiagnosisContent(record, dto);

        // 设置诊断时间
        if ("completed".equals(dto.getDiagnosis_status())) {
            record.setDiagnosis_time(LocalDateTime.now());
        }

        // 插入数据库
        diagnosisRecordMapper.insert(record);
        return record;
    }

    /**
     * 更新现有诊断记录
     */
    private DiagnosisRecord updateExistingRecord(DiagnosisRecord existingRecord, DiagnosisRecordDTO dto) {
        // 更新诊断内容（使用统一的方法）
        setDiagnosisContent(existingRecord, dto);

        // 如果状态变为已完成，设置诊断时间
        if ("completed".equals(dto.getDiagnosis_status())) {
            // 设置诊断时间（如果尚未设置）
            if (existingRecord.getDiagnosis_time() == null) {
                existingRecord.setDiagnosis_time(LocalDateTime.now());
            }
            // 更新就诊状态为完成
            PatientVisitDTO pvDTO = new PatientVisitDTO();
            pvDTO.setVisit_status("completed"); // 直接设置为完成状态
            pvDTO.setVisit_id(dto.getVisit_id());
            patientVisitMapper.updatePatientVisitCompleteStatus(pvDTO);
        }

        diagnosisRecordMapper.updateById(existingRecord);
        return existingRecord;
    }

    /**
     * 统一设置诊断内容（消除重复代码）
     */
    private void setDiagnosisContent(DiagnosisRecord record, DiagnosisRecordDTO dto) {
        record.setChief_complaint(dto.getChief_complaint());
        record.setPresent_illness(dto.getPresent_illness());
        record.setPhysical_exam(dto.getPhysical_exam());
        record.setPreliminary_diagnosis(dto.getPreliminary_diagnosis());
        record.setCurrent_diagnosis(dto.getCurrent_diagnosis());
        record.setTreatment_plan(dto.getTreatment_plan());
        record.setLab_results(dto.getLab_results());
        record.setDiagnosis_status(dto.getDiagnosis_status());
    }

    /**
     * 生成记录编号（服务层方法）
     */
    private String generateRecordNo(String appointmentId) {
        return DiagnosisRecordNoGenerator.generateRecordNo(appointmentId);
    }

    /**
     * 医生工作台
     * 患者预约挂号管理
     * 根据预约挂号id查询，当前患者详细的诊断记录
     * */
    public Response getDiagnosisRecordDetailByVisitId(DiagnosisRecordDTO dto){
        return Response.success(diagnosisRecordMapper.getDiagnosisRecordDetailByVisitId(dto));
    }

    /**
     * 医生工作台
     * 患者预约挂号管理
     * 根据记录id查询当前患者详细的诊断记录
     * */
    public Response getDiagnosisRecordDetailByRecordNo(DiagnosisRecordDTO dto){
        return Response.success(diagnosisRecordMapper.getDiagnosisRecordDetailByRecordNo(dto));
    }


    /**
     * //========================== 分页查询 =============================
     * */

    /**
     * 医生工作台
     * 获取指定医生的患者诊断记录分页数据总行数
     * */
    private Integer getDiagnosisRecordDataCountsBySearch(DoctorDiagnosisRecordQuery query){
        return diagnosisRecordMapper.getDiagnosisRecordDataCountsBySearch(query);
    }

    /**
     * 计算分页
     * */
    private Integer getDiagnosisRecordPageTotalBySearch(DoctorDiagnosisRecordQuery query){
        Integer diagnosisRecordCounts = getDiagnosisRecordDataCountsBySearch(query);
        Integer pageTotal = 1;//设置初始页码为1
        //数据总条数除以pageSize每页显示条数，如取余数求模，如果有余数，页码+1
        //如果可以整除，则页码等于数据总数除以pageSize
        pageTotal = diagnosisRecordCounts/query.getPageSize();
        if(diagnosisRecordCounts%query.getPageSize()>0){
            pageTotal += 1;
        }
        return pageTotal;
    }


    /**
     * 医生工作台
     * 获取指定医生的患者诊断记录分页数据
     * */
    private List<DiagnosisRecord> getDiagnosisRecordDataMapperBySearch(DoctorDiagnosisRecordQuery query){
        Integer currentPage = query.getCurrentPage();
        Integer startIndex = (currentPage - 1)*query.getPageSize();
        query.setStartIndex(startIndex);
        return diagnosisRecordMapper.getDiagnosisRecordDataMapperBySearch(query);
    }

    /**
     * 医生工作台
     * 装载数据：指定医生的患者诊断记录分页数据
     * */
    public Response getDiagnosisRecordPagerDataBySearch(DoctorDiagnosisRecordQuery query){
        PagerData pagerData = new PagerData();
        pagerData.setTotal(getDiagnosisRecordDataCountsBySearch(query));
        pagerData.setPageTotal(getDiagnosisRecordPageTotalBySearch(query));
        pagerData.setData(getDiagnosisRecordDataMapperBySearch(query));
        return Response.success(pagerData);
    }

}
